/*
 * Copyright (c) 2022 Kirky
 * Licensed under the Open Software Licence, Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/osl-3.0.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lingeringdream.luciole.helper.album;

import com.lingeringdream.luciole.AlbumAbility;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.engine.ImageEngine;
import com.zhihu.matisse.filter.Filter;
import com.zhihu.matisse.listener.OnCheckedListener;
import com.zhihu.matisse.listener.OnSelectedListener;
import com.zhihu.matisse.model.SelectionSpec;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.bundle.AbilityInfo;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Set;

/**
 * @author Kirky
 * @version 1.0
 * @date 2022/5/1
 */
public final class SelectionCreator {
    private final AlbumHelper mAlbumHelper;
    private final SelectionSpec mSelectionSpec;

    SelectionCreator(AlbumHelper albumHelper, Set<MimeType> set, boolean exclusive) {
        this.mAlbumHelper = albumHelper;
        this.mSelectionSpec = SelectionSpec.getCleanInstance();
        this.mSelectionSpec.mimeTypeSet = set;
        this.mSelectionSpec.mediaTypeExclusive = exclusive;
        this.mSelectionSpec.orientation = AbilityInfo.DisplayOrientation.PORTRAIT;
    }

    public SelectionCreator showSingleMediaType(boolean show) {
        this.mSelectionSpec.showSingleMediaType = show;
        return this;
    }

    /**
     * @deprecated
     */
    public SelectionCreator theme(int id) {
        this.mSelectionSpec.themeId = id;
        return this;
    }

    public SelectionCreator countable(boolean enable) {
        this.mSelectionSpec.countable = enable;
        return this;
    }

    public SelectionCreator maxSelectable(int max) {
        if (max < 1) {
            throw new IllegalArgumentException("maxSelectable must be greater than or equal to one");
        } else if (this.mSelectionSpec.maxImageSelectable <= 0 && this.mSelectionSpec.maxVideoSelectable <= 0) {
            this.mSelectionSpec.maxSelectable = max;
            return this;
        } else {
            throw new IllegalStateException("already set maxImageSelectable and maxVideoSelectable");
        }
    }

    public SelectionCreator maxSelectablePerMediaType(int maxImage, int maxVideo) {
        if (maxImage >= 1 && maxVideo >= 1) {
            this.mSelectionSpec.maxSelectable = -1;
            this.mSelectionSpec.maxImageSelectable = maxImage;
            this.mSelectionSpec.maxVideoSelectable = maxVideo;
            return this;
        } else {
            throw new IllegalArgumentException("max selectable must be greater than or equal to one");
        }
    }

    public SelectionCreator addFilter(Filter filter) {
        if (this.mSelectionSpec.filters == null) {
            this.mSelectionSpec.filters = new ArrayList<>();
        }

        if (filter == null) {
            throw new IllegalArgumentException("filter cannot be null");
        } else {
            this.mSelectionSpec.filters.add(filter);
            return this;
        }
    }

    public SelectionCreator capture(boolean capture) {
        this.mSelectionSpec.capture = capture;
        return this;
    }

    public SelectionCreator originalEnable(boolean enable) {
        this.mSelectionSpec.originalable = enable;
        return this;
    }

    public SelectionCreator autoHideToolbarOnSingleTap(boolean hide) {
        this.mSelectionSpec.autoHideToobar = hide;
        return this;
    }

    public SelectionCreator maxOriginalSize(int size) {
        this.mSelectionSpec.originalMaxSize = size;
        return this;
    }

    public SelectionCreator restrictOrientation(AbilityInfo.DisplayOrientation orientation) {
        this.mSelectionSpec.orientation = orientation;
        return this;
    }

    public SelectionCreator spanCount(int count) {
        if (count < 1) {
            throw new IllegalArgumentException("spanCount cannot be less than 1");
        } else {
            this.mSelectionSpec.spanCount = count;
            return this;
        }
    }

    public SelectionCreator gridExpectedSize(int size) {
        this.mSelectionSpec.gridExpectedSize = size;
        return this;
    }

    public SelectionCreator thumbnailScale(float scale) {
        if (scale > 0.0F && scale <= 1.0F) {
            this.mSelectionSpec.thumbnailScale = scale;
            return this;
        } else {
            throw new IllegalArgumentException("Thumbnail scale must be between (0.0, 1.0]");
        }
    }

    public SelectionCreator setOnSelectedListener(OnSelectedListener listener) {
        this.mSelectionSpec.onSelectedListener = listener;
        return this;
    }

    public SelectionCreator imageEngine(ImageEngine imageEngine) {
        this.mSelectionSpec.imageEngine = imageEngine;
        return this;
    }

    public SelectionCreator setOnCheckedListener(OnCheckedListener listener) {
        this.mSelectionSpec.onCheckedListener = listener;
        return this;
    }

    public void forResult(int requestCode) {
        Ability ability = this.mAlbumHelper.getAbility();
        if (ability != null) {
            Intent intent = new Intent();
            Operation operation = (new Intent.OperationBuilder())
                    .withDeviceId("")
                    .withBundleName(ability.getBundleName())
                    .withAbilityName(AlbumAbility.class.getName())
                    .build();
            intent.setOperation(operation);
            Fraction fraction = this.mAlbumHelper.getFraction();
            AbilitySlice abilitySlice = this.mAlbumHelper.getAbilitySlice();
            if (fraction != null) {
                fraction.startAbility(intent, requestCode);
            }

            if (abilitySlice != null) {
                abilitySlice.startAbilityForResult(intent, requestCode);
            } else {
                ability.startAbilityForResult(intent, requestCode);
            }
        }
    }

    public SelectionCreator showPreview(boolean show) {
        this.mSelectionSpec.showPreview = show;
        return this;
    }

    @Retention(RetentionPolicy.SOURCE)
    @interface ScreenOrientation {
    }
}

